﻿using Cache.CSRedis;
using Dapper;
using EventBus.Common;
using Microsoft.EntityFrameworkCore.Internal;
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;

namespace ProductWebApi.IntegratedEventService
{
    public class DeductionStockService : IEventHandler<DeductionStockEvent>
    {
        private readonly IRedisHelper _redisHelper;
        public DeductionStockService(IRedisHelper redisHelper)
        {
            _redisHelper = redisHelper;
        }

        public async Task HandleAsync(DeductionStockEvent @event)
        {
            if (!@event.SkuList.Any())
            {
                throw new Exception("sku不能为空!");
            }

            var connectionString = ConfigurationHelper.GetConnectionString();

            using (var connection = new MySqlConnection(connectionString))
            {
                try
                {
                    if (connection.State == ConnectionState.Closed)
                    {
                        await connection.OpenAsync().ConfigureAwait(false);
                    }

                    var sql = string.Empty;
                    foreach (var sku in @event.SkuList)
                    {
                        if (string.IsNullOrWhiteSpace(sku.SkuId))
                        {
                            throw new Exception($"{sku.SkuId}:skuId不能为空!");
                        }

                        if (sku.SkuQuantity == 0)
                        {
                            throw new Exception($"{sku.SkuId}:sku数量不能为0!");
                        }
                        sql += $"UPDATE t_sku SET Stock=Stock - {sku.SkuQuantity} where Id = '{sku.SkuId}' AND  Stock > {sku.SkuQuantity};";
                    }
                    //利用数据唯一索引做幂等
                    sql += $"INSERT INTO t_idempotent(UniqueCode) VALUES('{@event.UniqueCode}');";
                    var transaction = await connection.BeginTransactionAsync();
                    try
                    {
                        var i = await connection.ExecuteAsync(sql, null, transaction);
                        await transaction.CommitAsync();
                        if (i > 0)
                        {
                            Console.WriteLine("扣减库存成功!");
                        }
                        else
                        {
                            throw new Exception($"扣减库存失败!");
                        }
                    }
                    catch (MySqlException ex)
                    {
                        await transaction.RollbackAsync();
                        await transaction.DisposeAsync();

                        if (ex.Number == 1062)
                        {
                            //数据库以UniqueCode做了唯一索引，如何数据库违反了，唯一索引，说明该详细已经处理了
                            Console.WriteLine("数据已经处理成功了!");
                        }
                        else
                        {
                            //为其他数据库异常时，抛出异常！
                            throw new Exception(ex.Message);
                        }
                        
                    }

                }
                catch (Exception ex)
                {
                    throw new Exception($"扣减库存失败！{@event.SkuList.Select(e => e.SkuId).Join(",")}{ex.Message}");
                }
            }
        }
    }

}
